#!/usr/bin/perl -w
#for processing of pvaluelooper input files
#takes as input file with MMV data converted to "peak" and "not-peak"
#fasta format, data for each sequence on a single line;
#not-peak is represented by "1", and "peak" by 0
#program counts distances between peaks and for each position outputs the distance to the nearest peak, with distances separated by commas
#this multi-file version takes an input file containing a list of file names
#it opens each file, calculates distances, and prints an individual file for each 

#input list file name as $ARGV[0]

$INPUT = $ARGV[0];
open(FILE,$INPUT);

#open file with list of names of data input files
while ($filename = <FILE>){
	chomp $filename;
	#open data file and create output; 
	if(open(FASTA,$filename)){print "opened $filename\n";}
	else {print "failed to open $filename\n";}
	$output = $filename . "\.dist";
	open(OUTPUT,">$output");
#go thru lines in data file: if line is fasta header, print it to output, if line contains data calculate distances
while ($line = <FASTA>){
	#for header line:
	if ($line =~ ">"){
		$header = $line;
		print OUTPUT $header;
	}
	#for line with data:
	elsif ($line =~ ","){
		$forward = $line;
		chomp $forward;
		@forward = split(",",$forward);
		@reverse = ();
		#create reverse array; for some reason reversing $forward and splitting added an extra element
		foreach $element (@forward){
			unshift(@reverse,$element);
		}
		@forward_count = ();
		@reverse_count = ();
		$first_peak = 0;
		$last_peak = 0;
		$count = 0;
		$current_sum = 0;
		#calculate distance between peaks counting up from forward direction: add 1 at each non-peak and go back to zero at peak
		#also find locations of first and last peak in data
		foreach $distance (@forward){
			if ($distance == 0){
				++$count;
				push(@forward_count,$distance);
				$current_sum = 0;
				if ($last_peak == 0){$first_peak = $count;}
				$last_peak = $count;}	
			elsif ($distance == 1){
				++$count;
				++$current_sum;
				push(@forward_count,$current_sum);}
		}
		$count = 0;
		$current_sum = 0;
		#do the same counting but from reverse direction
		foreach $distance (@reverse){
			if ($distance == 0){
				++$count;
				push(@reverse_count,$distance);
				$current_sum = 0;}
			elsif ($distance == 1){
				++$count;
				++$current_sum;
				push(@reverse_count,$current_sum);}
				
		}
		#for each position, find the distance to the nearest peak
		#this number will be the smaller of the 2 distances from the forward and reverse counting, except
		#for positions before the first peak, where the distance is the reverse count, and 
		#for positions after the last peak, where it is the forward count
		$place = 0;
		until ((scalar @reverse_count == 0) and (scalar @forward_count == 0)){
			$fdist = shift @forward_count;
			$rdist = pop @reverse_count;
			++$place;
			if ($place < $first_peak){print OUTPUT $rdist,",";}
			elsif ($place > $last_peak or $place == $last_peak){print OUTPUT $fdist,",";}
			else {
				if ($fdist < $rdist){print OUTPUT $fdist,",";}
				else {print OUTPUT $rdist,",";}
			}		
		}	#close printing loop: end printing for sequence
		print OUTPUT "\n";
		
	
	}
 #close loop for data line
} 
#close loop thru data file
close FASTA;
}
 #close loop for cycling thru list of file names
close FILE;
exit;
